package com.quectel.core.module.device.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.quectel.constant.global.SqlConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.constants.RedisCacheConstants;
import com.quectel.core.module.device.dao.DeviceColumnDao;
import com.quectel.core.module.device.dto.DeviceCategoryDto;
import com.quectel.core.module.device.dto.DeviceColumnDto;
import com.quectel.core.module.device.dto.DeviceTypeDto;
import com.quectel.core.module.device.entity.DeviceColumnEntity;
import com.quectel.core.module.device.service.DeviceCategoryService;
import com.quectel.core.module.device.service.DeviceColumnService;
import com.quectel.core.module.device.service.DeviceTypeService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.kit.CacheKit;
import com.quectel.util.kit.Snowflake;
import com.quectel.util.redis.RedisUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 * @date 2019-05-31 12:10:45
 */
@DubboService
public class DeviceColumnServiceImpl implements DeviceColumnService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DeviceColumnServiceImpl.class);

    @Autowired
    private DeviceColumnDao deviceColumnDao;
    @Autowired
    private DeviceCategoryService deviceCategoryService;
    @Autowired
    private DeviceTypeService deviceTypeService;


    @Override
    public List<DeviceColumnDto> queryList(Map<String, Object> params) {
        List<DeviceColumnEntity> list = deviceColumnDao.queryList(params);
        List<DeviceColumnDto> columnDtoList = CopyUtils.copyList(list, DeviceColumnDto.class);
        //填充部分字段
        columnDtoList.forEach(this::padding);

        return columnDtoList;
    }

    @Override
    public int queryTotal(Map<String, Object> params) {
        return deviceColumnDao.queryTotal(params);
    }

    @Override
    public Long save(DeviceColumnDto dto) {
        DeviceColumnEntity entity = CopyUtils.copyObj(dto, DeviceColumnEntity.class);
        entity.setId(Snowflake.nextId());
        deviceColumnDao.insert(entity);
        return entity.getId();
    }

    @Override
    public void updateById(DeviceColumnDto dto) {

        RedisUtils.del(RedisCacheConstants.DEVICE_COLUMN_CACHE + dto.getId());

        DeviceColumnEntity entity = CopyUtils.copyObj(dto, DeviceColumnEntity.class);
        deviceColumnDao.updateById(entity);
    }

    @Override
    public DeviceColumnDto selectById(Long id) {

        DeviceColumnEntity entity = deviceColumnDao.selectById(id);
        DeviceColumnDto deviceColumnDto = CopyUtils.copyObj(entity, DeviceColumnDto.class);

        padding(deviceColumnDto);

        return deviceColumnDto;
    }

    @Override
    public void deleteById(Long id) {

        RedisUtils.del(RedisCacheConstants.DEVICE_COLUMN_CACHE + id);

        deviceColumnDao.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            deleteById(id);
        }
    }

    @Override
    public DeviceColumnDto queryByDeviceTypeIdAndName(Long deviceTypeId, String name) {
        DeviceColumnEntity deviceCurrentAlarmEntity = deviceColumnDao.selectOne(
                new LambdaQueryWrapper<DeviceColumnEntity>()
                        .eq(DeviceColumnEntity::getDeviceTypeId, deviceTypeId)
                        .eq(DeviceColumnEntity::getEntityName, name)
                        .last(SqlConstants.MYSQL_LIMIT_ONE));
        return CopyUtils.copyObj(deviceCurrentAlarmEntity, DeviceColumnDto.class);
    }

    @Override
    public List<DeviceColumnDto> queryAllColumnList(Map<String, Object> params) {
        List<DeviceColumnEntity> list = deviceColumnDao.queryAllColumnList(params);
        List<DeviceColumnDto> columnDtoList = CopyUtils.copyList(list, DeviceColumnDto.class);
        columnDtoList.forEach(this::padding);
        return columnDtoList;
    }

    private void padding(DeviceColumnDto deviceColumnDto) {
        //填充部分字段
        if (deviceColumnDto.getDeviceTypeId() != null) {
            DeviceTypeDto deviceTypeDto = deviceTypeService.selectCacheById(deviceColumnDto.getDeviceTypeId());
            if (deviceTypeDto != null) {
                deviceColumnDto.setDeviceTypeName(deviceTypeDto.getName());
            }
        }
        if (deviceColumnDto.getDeviceCategoryId() != null) {
            DeviceCategoryDto deviceCategoryDto = deviceCategoryService.selectCacheById(deviceColumnDto.getDeviceCategoryId());
            if (deviceCategoryDto != null) {
                deviceColumnDto.setDeviceCategoryName(deviceCategoryDto.getName());
            }
        }
    }

    @Override
    public void deleteByDeviceTypeId(Long deviceTypeId) {
        deviceColumnDao.delete(new LambdaQueryWrapper<DeviceColumnEntity>().eq(DeviceColumnEntity::getDeviceTypeId, deviceTypeId));
    }

    @Override
    public List<DeviceColumnDto> selectByDeviceTypeId(Long deviceTypeId) {
        return CacheKit.cacheToRedis(
                () -> {
                    List<DeviceColumnEntity> deviceColumnEntities = deviceColumnDao.selectList(new LambdaQueryWrapper<DeviceColumnEntity>()
                            .eq(DeviceColumnEntity::getDeviceTypeId, deviceTypeId));
                    return CopyUtils.copyList(deviceColumnEntities, DeviceColumnDto.class);
                },
                RedisCacheConstants.DEVICE_COLUMN_LIST_CACHE + deviceTypeId,
                SystemConstants.NOT_NULL_CACHE_EXPIRE_SECONDS
        );
    }
}
